// Η function πλακόστρωση δημιουργεί το τερέν πλακοστρώνοντας το μεγαλύτερο μέρος της
// διαθέσιμης περιοχής με πλακίδια. Το σκουλήκι αποτελείται από μονάδες που ονομάζονται
// «κύτταρα» και κάθε κύτταρο καταλαμβάνει ένα πλακίδιο.
//
// Μπορούμε να περάσουμε ως παραμέτρους τη γραμμή και τη στήλη του πλακιδίου της κεφαλής
// του σκουληκιού.

Skolix.plakostrosi = function(kefaliRow, kefaliCol) {
	var row, col, grami;

	Skolix.teren.empty();
	Skolix.cpanel.css('display', 'none');

	// Αφήνουμε λίγο χώρο στο κάτω μέρος της σελίδας και περισσότερο δεξιά, όπου
	// υπάρχει το control panel.

	Skolix.rows = parseInt(Skolix.selida.innerHeight() / Skolix.size) - 1;
	Skolix.cols = parseInt(Skolix.selida.innerWidth() / Skolix.size) - 2;

	for (row = 1; row <= Skolix.rows; row++) {
		grami = $('<div>').appendTo(Skolix.teren);
		for (col = 1; col <= Skolix.cols; col++) {
			grami.append($('<div>').addClass('plakidio').
			attr('id', 'L' + row + 'X' + col).data({
				row: row,
				col: col,
			}).

			// Κάθε πλακίδιο περιέχει το υπόστρωμα. Πρόκειται για το
			// πλακάκι της αρεσκείας μας.

			append($('<img>').addClass('plakidioIcon').attr({
				id: 'P' + row + 'X' + col,
				src: Skolix.plakidio,
			}).data('ixnos', 0)).

			// Σε κάθε πλακίδιο περιέχεται επίσης και ένα εν δυνάμει
			// κύτταρο του σκουληκιού.

			append($('<img>').addClass('kitaroIcon').attr({
				id: 'K' + row + 'X' + col,
				src: 'ikona/skolix/skolix.png',
			}).data({
				row: row,
				col: col,
			})).

			append($('<div>').attr('id', 'I' + row + 'X' + col).addClass('ixnos').
			css('display', Skolix.sonxi ? 'inline' : 'none')).

			// Κάνοντας κλικ σε οποιοδήποτε πλακίδιο, υποδηλώνουμε ότι
			// επιθυμούμε την κεφαλή του σκουληκιού στο συγκεκριμένο
			// πλακίδιο.

			on('click', function(e) {
				e.stopPropagation();
				Skolix.kefaliSet($(this));
			}));
		}
	}

	// Επανεμφανίζουμε το control panel και εφόσον έχουν καθοριστούν στοιχεία
	// κεφαλής προχωρούμε στον καθορισμό κεφαλής.

	Skolix.cpanel.css('display', 'inline');
	if (arguments.length === 2) Skolix.kefaliSet($('#L' + kefaliRow + 'X' + kefaliCol));
}

// Με την "kefaliSet" καθορίζουμε νέα κεφαλή του σκουληκιού. Αυτό γίνεται κάνοντας κλικ
// σε οποιοδήποτε πλακίδιο, οπότε η κεφαλή του σκουληκιού θα τοποθετηθεί στο συγκεκριμένο
// πλακίδιο. Η ουρά τοποθετείται στο επάνω αριστερά τετράγωνο του τερέν και το σκουλήκι
// εκτείνεται βουστροφηδόν μέχρι την κεφαλή. Επανακαθορισμός της ιδίας κεφαλής εκκινεί
// την κίνηση του σκουληκιού.

Skolix.kefaliSet = function(kefali) {
	var row, col, i;

	// Αν το σκουλήκι βρίσκεται ήδη σε κίνηση, τότε προχωρούμε σε ακύρωση της κινήσεως
	// και σε επανασχηματισμό του τερέν.

	if (Skolix.energo) return Skolix.reset(kefali);

	// Το σκουλήκι είτε είναι ακίνητο, είτε δεν έχει ακόμη δημιουργηθεί. Αποσπούμε τα
	// στοιχεία θέσης του επιθυμητού πλακιδίου κεφαλής και εφόσον είναι η δεύτερη φορά
	// που επανακαθορίζουμε το ίδιο κεφάλι εκκινούμε την κίνηση του σκουληκιού.

	Skolix.kefaliRow = kefali.data('row');
	Skolix.kefaliCol = kefali.data('col');
	if ($('#K' + Skolix.kefaliRow + 'X' + Skolix.kefaliCol).data('kefali')) {
		Skolix.energo = true;
		Skolix.kinisi();
		return;
	}

	// Είναι η πρώτη φορά που καθορίζουμε την κεφαλή του σκουληκιού στο συγκεκριμένο
	// πλακίδιο, επομένως σχηματίζουμε το σκουλήκι.

	Skolix.skolix = [];
	$('.kitaroIcon').removeClass('kitaroOn').removeData('kefali').attr('src', 'ikona/skolix/skolix.png');

	for (row = 1; row < Skolix.kefaliRow; row++) {
		for (col = 1; col <= Skolix.cols; col++) Skolix.skolix.push($('#K' + row + 'X' + col));
	}

	for (col = 1; col <= Skolix.kefaliCol; col++) {
		Skolix.skolix.push($('#K' + Skolix.kefaliRow + 'X' + col));
	}

	$('#K' + Skolix.kefaliRow + 'X' + Skolix.kefaliCol).attr('src', 'ikona/skolix/anamoni.png').data('kefali', true);
	for (i = 0; i < Skolix.skolix.length; i++) Skolix.skolix[i].addClass('kitaroOn');
	Skolix.ouraSet();
}

// Η "reset" καλείται όταν κατά την κίνηση του σκουληκιού κάνουμε κλικ σε οποιοδήποτε πλακίδιο
// τρερέν, πράγμα που σημαίνει ότι επιθυμούμε διακοπή της κινήσεως και επανακαθορισμό της κεφαλής
// νέου σκουληκιού.

Skolix.reset = function(kefali) {
	delete Skolix.energo;
	if (Skolix.epomeni) clearTimeout(Skolix.epomeni);
	Skolix.skolix.pop().attr('src', 'ikona/skolix/diakopi.png');
	setTimeout(function() {
		Skolix.plakostrosi(kefali.data('row'), kefali.data('col'));
	}, 10);
}

// Η "ouraSet" καλείται κατά τη μετακίνηση του σκουληκιού και σκοπό έχει να αλλάξει την εικόνα
// του πλακιδίου της ουράς του σκουληκιού σε κύτταρο ουράς, εκτός κι αν το σκουλήκι μας είναι
// μοναδιαίο, οπότε υπερτερεί η εικόνα της κεφαλής.

Skolix.ouraSet = function() {
	if (Skolix.skolix.length < 2) return;
	Skolix.skolix[0].attr('src', 'ikona/skolix/oura.png');
	return Skolix;
}

Skolix.ouraFora = function(prev) {
	var oura = Skolix.skolix[0], prevRow, prevCol, toraRow, toraCol;

	prevRow = prev.data('row');
	prevCol = prev.data('col');

	toraRow = oura.data('row');
	toraCol = oura.data('col');
}

// Η function "kinisi" είναι η καρδιά της κίνησης του σκουληκιού. Οι δυνατές κατευθύνσεις είναι:
//
//	0	πάνω
//	1	δεξιά
//	2	κάτω
//	3	αριστερά
//
// Η κατεύθυνση επιλέγεται εν πολλοίς στην τύχη. Αν η κατεύθυνση που επιλεγεί δεν είναι βατή, π.χ.
// οδηγεί εκτός τερέν, ή οδηγεί σε πλακίδιο ήδη κατειλημμένο, μπαίνουμε σε διαδικασία εξάντλησης
// και των τριών υπόλοιπων κατευθύνσεων τις οποίες δοκιμάζουμε με τη σειρά είτε δεξιόστροφα, είτε
// αριστερόστροφα (αυτό επιλέγεται με πιθανότητα 50%). Σ' αυτή την περίπτωση η function καλείται
// με παραμέτρους την ήδη καθορισμένη κατεύθυνση και το βάθος, δηλαδή τη βαθμό επανάληψης λόγω
// άβατου.

Skolix.kinisi = function(dir, level) {
	var kefaliRow = Skolix.kefaliRow, kefaliCol = Skolix.kefaliCol, oura;

	dir = (dir === undefined ? Skolix.apofasi() : (dir + 4) % 4);
	if (level === undefined) level = 0;
	else if (level > 3) return Skolix.adiexodo();

	switch (dir) {
	case 0: kefaliRow--; break;
	case 1: kefaliCol++; break;
	case 2: kefaliRow++; break;
	default: kefaliCol--; break;
	}

	// Εξετάζουμε αν με την επιλεγείσα κατεύθυνση βγαίνουμε εκτός τερέν.

	if (kefaliRow > Skolix.rows) return Skolix.enalaktiki(dir, level);
	if (kefaliRow < 1) return Skolix.enalaktiki(dir, level);
	if (kefaliCol > Skolix.cols) return Skolix.enalaktiki(dir, level);
	if (kefaliCol < 1) return Skolix.enalaktiki(dir, level);

	// Κατόπιν εξετάζουμε αν με την επιλεγείσα κατεύθυνση οδηγούμαστε σε ήδη
	// κατειλημμένο πλακίδιο.

	if ($('#K' + kefaliRow + 'X' + kefaliCol).hasClass('kitaroOn')) return Skolix.enalaktiki(dir, level);

	// Η κατεύθυνση που έχει επιλεγεί μας οδηγεί σε ελεύθερο πλακίδιο, επομένως
	// προχωρούμε στην υλοποίηση της κινήσεως προς τη συγκεκριμένη κατεύθυνση.

	$('#K' + Skolix.kefaliRow + 'X' + Skolix.kefaliCol).
	removeData('kefali').
	attr('src', 'ikona/skolix/skolix.png');

	Skolix.kefaliRow = kefaliRow;
	Skolix.kefaliCol = kefaliCol;

	Skolix.skolix.push($('#K' + Skolix.kefaliRow + 'X' + Skolix.kefaliCol).
	data('kefali', true).
	attr('src', 'ikona/skolix/kinisi.png').
	addClass('kitaroOn'));
	Skolix.ixnos(kefaliRow, kefaliCol);

	oura = Skolix.skolix[0].removeClass('kitaroOn');
	Skolix.skolix.splice(0, 1);
	Skolix.ouraSet().ouraFora(oura);

	// Κρατάμε την κατεύθυνση που επιλέξαμε και δρομολογούμε την επόμενη κίνηση.

	Skolix.dromos = dir;
	Skolix.epomeni = setTimeout(Skolix.kinisi, Skolix.speed);
}

Skolix.ixnos = function(row, col) {
	var plakidio = $('#P' + row + 'X' + col), ixnos;
	plakidio.data('ixnos' , ixnos = plakidio.data('ixnos') + 1);
	$('#I' + row + 'X' + col).text(ixnos);
}

// Η function "apofasi" είναι αυτή που αοφασίζει ποια κατεύθυνση θα ακολουθήσει το
// σουλήκι λαμβάνοντας υπόψη τον βαθμό επιμονής. Βαθμός επιμονής είναι ένας ακέραιος
// αριθμός που δείχνει πόσο συχνά θα έχουμε αλλαγή κατεύθυνσης. Αν, π.χ. ο βαθμός
// επιμονής είναι 5, τότε θα επιχειρείται αλλαγή κατεύθυνησης περίπου μια στις πέντε
// φορές.

Skolix.apofasi = function() {
	return Math.floor(Math.random() * Skolix.epimoni) ? Skolix.dromos : Math.floor(Math.random() * 4);
}

// Η function "enalaktiki" καλείται όποτε η κατεύθυνση που επιλέχθηκε οδηγεί σε άβατο.
// Σ' αυτήν την περίπτωση επιλέγεται με πιθανότητα 50% δεξιόστροφη ή αριστερόστροφη
// εξαντλητική επιλογή των υπολοίπων κατευθύνσεων.

Skolix.enalaktiki = function(dir, level) {
	// Στο πρώτο επίπεδο (level = 0) επιλέγεται ο τρόπος επιλογής των κατευθύνσεων
	// που απομένουν να ελεγχθούν. Είτε θα δοκιμάζουμε δεξιόστροφα (1), είτε
	// αριστερόστροφα (-1).

	if (!level) Skolix.dexiostrofa = (Math.random() < 0.5 ? 1 : -1);
	return Skolix.kinisi(dir + Skolix.dexiostrofa, level + 1);
}

Skolix.adiexodo = function() {
	$('#K' + Skolix.kefaliRow + 'X' + Skolix.kefaliCol).attr('src', 'ikona/skolix/adiexodo.png').
	delay(1000).animate({
		height: parseInt(Skolix.size / 1.2) + 'px',
	}, 1000, 'easeOutBounce');
}

Skolix.controls = function() {
	Skolix.cpanel.
	append($('<img>').addClass('cpanelIcon').attr({
		src: 'ikona/cpanel/grigora.png',
		title: 'Γρήγορο',
	}).
	on('click', function(e) {
		e.stopPropagation();
		Skolix.speed = Math.floor(Skolix.speed / 2);
		if (Skolix.speed < 10) Skolix.speed = 10;
		$('#taxitita').text(parseInt(999 / Skolix.speed));
	})).
	append($('<div>').addClass('cpanelKimeno').attr({
		id: 'taxitita',
	}).text(parseInt(999 / Skolix.speed)).attr('title', 'Ταχύτητα')).
	append($('<img>').addClass('cpanelIcon').css('margin', '6px 0 0 8px').attr({
		src: 'ikona/cpanel/arga.png',
		title: 'Αργό',
	}).
	on('click', function(e) {
		e.stopPropagation();
		Skolix.speed *= 2;
		$('#taxitita').text(parseInt(999 / Skolix.speed));
	})).
	append($('<img>').addClass('cpanelIcon').attr({
		src: 'ikona/skolix/zoiro.png',
		title: 'Ζωηρό',
	}).
	on('click', function(e) {
		e.stopPropagation();
		Skolix.epimoni--;
		if (Skolix.epimoni < 0) Skolix.epimoni = 0;
		$('#epimoni').text(Skolix.epimoni);
	})).
	append($('<div>').addClass('cpanelKimeno').attr({
		id: 'epimoni',
	}).text(Skolix.epimoni).attr('title', 'Χαλαρότητα')).
	append($('<img>').addClass('cpanelIcon').css('margin', '6px 0 0 8px').attr({
		src: 'ikona/skolix/xalaro.png',
		title: 'Χαλαρό',
	}).
	on('click', function(e) {
		e.stopPropagation();
		Skolix.epimoni++;
		$('#epimoni').text(Skolix.epimoni);
	})).
	append($('<img>').addClass('cpanelIcon').attr({
		src: 'ikona/plakidio/folida.png',
		title: 'Πλακόστρωση',
	}).
	on('click', function(e) {
		e.stopPropagation();
		Skolix.plakidio = $(this).attr('src');
		$('.plakidioIcon').attr('src', Skolix.plakidio);

		switch (Skolix.plakidio) {
		case 'ikona/plakidio/marmaro.png': src = 'ikona/plakidio/folida.png'; break;
		case 'ikona/plakidio/folida.png': src = 'ikona/plakidio/marmaro.jpg'; break;
		case 'ikona/plakidio/marmaro.jpg': src = 'ikona/plakidio/tounel.gif'; break;
		case 'ikona/plakidio/tounel.gif': src = 'ikona/plakidio/marmaro.png'; break;
		}
		$(this).attr('src', src);
	})).
	append($('<img>').addClass('cpanelIcon').attr({
		src: 'ikona/cpanel/ixnos.png',
		title: 'Ίχνος',
	}).
	on('click', function(e) {
		e.stopPropagation();
		if (Skolix.sonxi) $('.ixnos').css('display', 'none');
		else $('.ixnos').css('display', 'inline');
		Skolix.sonxi = !Skolix.sonxi;
	}));
}

$(document).ready(function() {
	Skolix.selida = $(document);
	Skolix.teren = $('#teren').css('verticalAlign', 'top');
	Skolix.cpanel = $('#cpanel').css('verticalAlign', 'top');
	Skolix.dromos = 1;
	Skolix.sonxi = false;
	Skolix.plakidio = 'ikona/plakidio/marmaro.png';
	Skolix.plakostrosi();
	Skolix.controls();
});

$(window).on('resize', Skolix.plakostrosi);
